﻿using System;
using System.Collections.Generic;
using System.Linq;
using LunchCommand.Models;

namespace LunchCommand.ViewModels
{
    /// <summary>
    /// The view model for the main page.  It's kind of a big deal
    /// </summary>
    public class LunchCommandViewModel
    {
        public LunchCommandViewModel()
        {

        }

        public LunchCommandViewModel(User user, Lunch lunch, IEnumerable<Venue> allVenues, IEnumerable<User> allUsers, IEnumerable<Venue> possibleVenues)
        {
            this.User = user;
            this.TodaysLunch = lunch;
            this.VenueChoicesForUser = allVenues.OrderBy(v => v.Name)
                .Select(v => new VenueChoiceViewModel(
                    v, // Venue
                    user.VenueDecisions.Where(vc => vc.Venue.VenueID == v.VenueID).Select(vc => vc.Degree).FirstOrDefault(), // Degree of preference
                    v.UsersWhoChose.Count(u => u.Degree == DegreeOfPreference.WantToGo), // Count of other users
                    v.DateCreated > user.LastTimeVenueDecisionMade && v.CreatedBy != null && v.CreatedBy.UserId != user.UserId)); // Is new

            // Get the decision for today's lunch
            var lunchDecision = user.LunchesDecided.FirstOrDefault(l => l.LunchId == lunch.LunchId);
            this.UserIsGoingToday = lunchDecision != null && lunchDecision.Decision;
            this.UserHasDecidedToday = lunchDecision != null;

            // Get the list of users going today and those not going
            this.UsersToday =
                allUsers.Select(u =>
                {
                    var decision = lunch.Users.FirstOrDefault(u2 => u2.UserId == u.UserId);

                    bool? going = null;

                    if (decision != null)
                    {
                        going = decision.Decision;
                    }
                    return new Tuple<String, Boolean?>(u.Name, going);

                }).OrderBy(z => z.Item2.HasValue ? z.Item2.Value ? 1 : 2 : 3);  // Good luck reading THAT

            this.PossibleVenues = possibleVenues.Distinct();
        }

        /// <summary>
        /// The lunch du jor
        /// </summary>
        public Lunch TodaysLunch { get; set; }

        /// <summary>
        /// The user
        /// </summary>
        public User User { get; set; }

        /// <summary>
        /// The user's venue decisions
        /// </summary>
        public IEnumerable<VenueChoiceViewModel> VenueChoicesForUser { get; set; }

        /// <summary>
        /// Whether or not the user has made a decision to go today
        /// </summary>
        public Boolean UserHasDecidedToday { get; set; }

        /// <summary>
        /// Whether or not the user is going to lunch today.  This is meaningless is <c>UserHasDecidedToday</c> is <c>false</c>
        /// </summary>
        public Boolean UserIsGoingToday { get; set; }

        /// <summary>
        /// All of the other users today.  Item1 is the users' names and Item2 is their decision states
        /// </summary>
        public IEnumerable<Tuple<String, Boolean?>> UsersToday { get; private set; }

        /// <summary>
        /// (This is from the client) whether or not the user clicked Save Changes at the bottom of the venue column.
        /// We need to know this because when they make a lunch decision, it is the same postback as when they save venue choices
        /// </summary>
        public Boolean VenueChoicesMade { get; set; }

        /// <summary>
        /// The collection of today's possible venues
        /// </summary>
        public IEnumerable<Venue> PossibleVenues { get; set; }

        /// <summary>
        /// Whether or not any venue is new to the user
        /// </summary>
        public Boolean AnyVenuesNew
        {
            get
            {
                return this.VenueChoicesForUser.Any(v => v.IsNew);
            }
        }
    }
}